import talib
import pandas as pd
import requests
import json
import matplotlib
# matplotlib.use('TkAgg')  # 或 'Qt5Agg'
matplotlib.use('Agg')  # 必须在 import pyplot 前设置！
import matplotlib.pyplot as plt

def api_to_dataframe(url, params=None, json_path=None):
    """
    获取HTTP API数据并转换为DataFrame
    Args:
        url: API地址
        params: 请求参数
        json_path: JSON数据中包含数组的路径（如 'data.result'）
    """
    try:
        # 发送请求
        response = requests.get(url, params=params)
        response.raise_for_status()  # 检查请求是否成功

        # 解析JSON
        data = response.json()

        # 如果指定了JSON路径，提取嵌套数据
        if json_path:
            keys = json_path.split('.')
            for key in keys:
                data = data[key]

        # 转换为DataFrame
        df = pd.DataFrame(data)
        return df

    except requests.exceptions.RequestException as e:
        print(f"请求错误: {e}")
        return pd.DataFrame()
    except json.JSONDecodeError as e:
        print(f"JSON解析错误: {e}")
        return pd.DataFrame()





def calculate_kdj_talib(high, low, close, fastk_period=9, slowk_period=3, slowd_period=3):
    """
    使用TA-Lib计算KDJ指标（最快的方法）
    """
    # TA-Lib的STOCH函数就是KDJ指标
    slowk, slowd = talib.STOCH(high, low, close,
                               fastk_period=fastk_period,
                               slowk_period=slowk_period,
                               slowk_matype=0,
                               slowd_period=slowd_period,
                               slowd_matype=0)

    # 计算J值：J = 3K - 2D
    j = 3 * slowk - 2 * slowd

    return slowk, slowd, j



    #赫尔均线
    # MAH1: WMA(2 * WMA(C, ROUND(N / 2)) - WMA(C, N), ROUND(SQRT(N)));
    # MAH2: WMA(2 * WMA(C, ROUND(M / 2)) - WMA(C, M), ROUND(SQRT(M)));


def _ensure_datetime_index(df, time_col):
    """确保DataFrame有日期时间索引"""
    if time_col is not None:
        # 如果指定了时间列，将其设为索引
        df = df.set_index(pd.to_datetime(df[time_col]))
        df = df.drop(columns=[time_col])
    elif not isinstance(df.index, pd.DatetimeIndex):
        # 如果索引不是日期时间，尝试转换
        try:
            df.index = pd.to_datetime(df.index)
        except:
            raise ValueError("无法将索引转换为日期时间，请指定time_col参数")

    # 按时间排序
    df = df.sort_index()
    return df


def _inner_merge_by_time(df1, df2, tolerance):
    """内连接合并"""
    # 找到时间交集
    common_start = max(df1.index.min(), df2.index.min())
    common_end = min(df1.index.max(), df2.index.max())

    if common_start > common_end:
        raise ValueError("两个DataFrame没有时间交集")

    print(f"时间交集: {common_start} 到 {common_end}")

    # 使用merge_asof进行近似匹配（如果有容差）
    if tolerance is not None:
        df1_reset = df1.reset_index()
        df2_reset = df2.reset_index()

        merged = pd.merge_asof(
            df1_reset.sort_values('index'),
            df2_reset.sort_values('index'),
            on='index',
            tolerance=pd.Timedelta(tolerance),
            direction='nearest'
        )
        merged = merged.set_index('index')
    else:
        # 精确匹配
        merged = df1.join(df2, how='inner', lsuffix='_df1', rsuffix='_df2')

    return merged


# 设置中文字体（解决中文显示问题）
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

def plot_basic_line_chart(df1,df2):


    """绘制基本价格折线图"""
    plt.figure(figsize=(12, 6))

    # o float 开盘价
    # h float 最高价
    # l float 最低价
    # c float 收盘价
    # v float 成交量
    # a float 成交额

    # 合并：以 df1 为主（left join），只取 df2 的 'value' 列
    df1 = pd.merge(df1, df2[['t', 'macd88']], on='t', how='left')


    plt.plot(df1.index, df1['macd21'], label='21线', color='blue', linewidth=2)
    plt.plot(df1.index, df1['macd88'], label='88线', color='green', linewidth=2)
    # plt.plot(df.index, df['h'], label='最高价', color='red', linewidth=1, alpha=0.5, linestyle='--')
    # plt.plot(df.index, df['l'], label='最低价', color='purple', linewidth=1, alpha=0.5, linestyle='--')

    plt.title("丽岛建材赫尔均线", fontsize=16, fontweight='bold')
    plt.xlabel('日期', fontsize=12)
    plt.ylabel('价格 (元)', fontsize=12)
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.xticks(rotation=45)
    plt.tight_layout()

    return plt




def simplest_plot_test():
    """最简单的绘图测试"""
    try:
        # 创建最简单的数据
        x = [1, 2, 3, 4, 5]
        y = [10, 20, 15, 25, 30]

        # 创建图形
        plt.figure(figsize=(8, 4))
        plt.plot(x, y, 'b-', linewidth=2)
        plt.title('最简单的测试图表')
        plt.xlabel('X轴')
        plt.ylabel('Y轴')
        plt.grid(True, alpha=0.3)
        plt.show()

        print("✅ 简单绘图测试成功！")
        return True

    except Exception as e:
        print(f"❌ 简单绘图失败: {e}")
        return False


def filter_by_time_attributes(df):
    """
    基于时间属性过滤数据（年、月、日、小时、星期几、季度）
    """

    # 方法3: 使用between方法
    print("\n3. Between方法过滤 (2024年3月数据)")
    mar_data = df[df['t'].between('2025-11-06', '2025-11-08')]
    print(f"3月数据行数: {len(mar_data)}")

    return mar_data

import txd.txd as txd
import datasource.tx as tx
import datasource.mairuiapi as mr

import task_init as task
import utils.oss as oss
if __name__ == '__main__':
    print("主程序开始启动")


    # task.init_task_zb()




    # x = tx.TxData()
    # txdf =x.tx_data_k()
    # t=txd.TxdClass()
    # t.txd_kdj()
    #
    # mair =mr.MaiRuiData()
    # mairdf =mair.mai_rui_data_k("603937.SH")
    # t.txd_kdj(mairdf)

    # close_prices21 = txdf['收盘价'].values
    # x1 =t.tdx_double_wma_single_param(close_prices21,21)
    #
    #
    # print(x1[['时间','收盘价','l', 'c', 'macd21']].tail(100))


    # # 使用示例
    # url = "https://y.mairuiapi.com/hsstock/history/603937.SH/5/n/E1D401B9-E30D-4617-91EA-4313D968876D?st=20251104133000&et=20251108093000&lt=10000"
    # params = "" #{"symbol": "000001", "period": "daily"}
    # df21 = api_to_dataframe(url, params)
    # url = "https://y.mairuiapi.com/hsstock/history/603937.SH/5/n/E1D401B9-E30D-4617-91EA-4313D968876D?st=20251104093000&et=20251108093000&lt=10000"
    # df88 = api_to_dataframe(url, params)
    # # print(df.head())
    #

    ## # 字段名称 数据类型 字段说明
    # # t string 交易时间
    # # o float 开盘价
    # # h float 最高价
    # # l float 最低价
    # # c float 收盘价
    # # v float 成交量
    # # a float 成交额
    # # pc float 前收盘价
    # # sf int 停牌 1 停牌，0  不停牌
    # #获取通信达分钟级别的数据
    # # txd_kdj(df)
    #
    # close_prices21 = df21['c'].values  # 获取收盘价序列
    #
    #
    # close_prices88 = df88['c'].values  # 获取收盘价序列
    #
    # x =macd.tdx_double_wma_single_param(close_prices21,21)
    # df21['macd21'] = x
    #
    # y =macd.tdx_double_wma_single_param(close_prices88,88)
    # df88['macd88'] = y
    #
    # # 年、月、日、小时
    # df211 =filter_by_time_attributes(df21)
    # df881 =filter_by_time_attributes(df88)
    #
    # print(df211[['t','h','l', 'c', 'macd21']].tail(100))
    # print(df881[['t','h','l', 'c', 'macd88']].tail(100))
    #
    # # 运行测试
    # # simplest_plot_test()
    #
    # # 使用示例
    # plot_basic_line_chart(df211,df881)
    #
    # plt.show()
    #
    # # 主程序继续执行
    # for i in range(100):
    #     print(f"主程序执行任务 {i + 1}/10")
    #     time.sleep(10)

    print("主程序任务完成")
    # 图形线程会继续运行直到用户关闭窗口


